package prop;

import java.util.LinkedList;
import java.util.Vector;

/**
 * Es la clase para representar los temas en la aplicacion
 * @author Sandra Crespo
 */
public class Tema {

    String nombre;
    Vector<PalabraParaAnadir> llpalabra;
    Vector<NoticiaClasificada> llnoticia;

    /** 
     * Crea un Tema vacio
     */
    public Tema() {
        /*** {PRE:-}
         * {POST: se crea un tema vacio}
         */
        llpalabra = new Vector<PalabraParaAnadir>();
        llnoticia = new Vector<NoticiaClasificada>();
    }

    /** 
     * Crea un Tema cuyo nombre sea t
     * @param t Nombre del Tema
     */
    public Tema(String t) {
        /*** {PRE:-}
         * {POST: se crea un tema con el nombre t}
         */
        nombre = t;
        llpalabra = new Vector<PalabraParaAnadir>();
        llnoticia = new Vector<NoticiaClasificada>();
    }

    /** 
     * Consulta el Nombre del tema
     * @return devuelve el nombre del tema
     */
    public String getNombre() {
        /*** {PRE:-}
         * {POST:devuelve el nombre del Tema}*/
        return nombre;
    }

    /** 
     * Consulta el las palabras que estan asociadas con el Tema
     * @return devuelve el vector con los punteros a las palabras asociadas con el tema
     */
    public Vector<PalabraParaAnadir> getPalabras() {
        /*** {PRE:-}
         * {POST:devuelve un Vector de punteros de las PalabraParaAnadir del Tema. El Vector puede estar vacio}*/
        return llpalabra;
    }

    /** 
     * Consulta si la palabra esta asociada a tema
     * @param palabra es el nombre de la palabra que se desea consultar si es palabra clave del tema.
     * @return devuelve un booleano que indica si hay una palabra asociada con el tema que tenga el nombre.
     */
    public boolean esPalabraClave(String palabra) {
        /*** {PRE:-}
         * {POST:true: si hay una PalabraParaAnadir asociada a Tema cuyo nombre sea palabra. false: si no hay ninguna PalabraParaAnadir asociada a Tema cuyo nombre sea palabra}*/
        for (PalabraParaAnadir p : llpalabra) {
            if (palabra.equals(p.getValor())) {
                return true;
            }
        }
        return false;
    }

    /** 
     * Consulta las noticias clasificadas que tienen asociado el tema.
     * @return devuelve un vector de punteros a las noticias clasificadas que tienen asociado el tema
     */
    public Vector<NoticiaClasificada> getNoticiasClasificadas() {
        /*** {PRE:-}
         * {POST:devuelve un Vector de punteros de las NoticiasClasificadas que sean del Tema. El Vector puede estar vacio}*/
        return llnoticia;
    }

    /** 
     * Consulta si la noticia esta asociada al tema
     * @param noticia es el nombre de la notica que se desea consultar si es noticia clasificada del tema.
     * @return deuelve un booleano que indica si hay una noticia asociada con el tema que tenga el nombre.
     */
    public boolean esNoticiaClasificada(String noticia) {
        /*** {PRE:-}
         * {POST:true: si hay una NoticiaClasificada asociada a Tema cuyo titulo sea noticia. false: si no hay ninguna NoticiaClasificada asociada a Tema cuyo titulo sea noticia}*/
        for (NoticiaClasificada not : llnoticia) {
            if (noticia.equals(not.getTitulo())) {
                return true;
            }
        }
        return false;
    }

    /** 
     * Anade una noticia clasificada al tema
     * @param nc es la noticia clasificada que se desea asociar al tema
     * @return devuelve un booleano que indica la noticia clasificada se ha asociado correctamente al tema.
     */
    public boolean addNoticiaClasificada(NoticiaClasificada nc) {
        /*** {PRE:nc!=null}
         * {POST:true: si la noticiaClasificada nc se ha anadido correctamente. false: si no se ha anadido correctamente}*/
        return llnoticia.add(nc);
    }

    /** 
     * Consulta el numero de noticias clasificadas que estan asociadas con el tema
     * @return devuelve el numero de noticias que estan clasificadas y estan asociadas con el tema.
     */
    public int numeroNoticiasClasificadas() {
        /*** {PRE:-}
         * {POST: devuelve el numero de NoticiasClasificadas asociadas con el Tema}*/
        return llnoticia.size();
    }

    /** 
     * Consulta el numero de palabras que estan asociadas con el tema
     * @return devuelve el numero de palabras que estan asociadas con el tema.
     */
    public int numeroPalabrasTema() {
        /*** {PRE:-}
         * {POST: devuelve el numero de PalabraParaAnadir asociadas al Tema}*/
        return llpalabra.size();
    }

    /** 
     * Anade una palabra al tema
     * @param palabra es la palabra que se desea asociar con el tema
     * @return devuelve un booleano que indica si la palabra se ha correctamente al tema.
     */
    public boolean addPalabra(PalabraParaAnadir palabra) {
        /*** {PRE:palabra!=null}
         * {POST:true: si la PalabraParaAnadir palabra se ha anadido correctamente. false: si no se ha anadido correctamente}*/
        return llpalabra.add(palabra);
    }

    /** 
     * Calcula el vector centroide de la noticia.
     * @param N es el numero de palabras que tenemos en el diccionario.
     * @return devuelve una LinkedList con el id de la palabra y la componente del vector centroide para esa palabra.
     */
    public LinkedList<IdFrec> getVectorCentroide(int N) {
        /*** {PRE:-}
         * {POST:true: devuelve una LinkedList con el id de la palabra y la componente del vector centroide para esa palabra.}*/
        LinkedList<IdFrec> vectorC2 = new LinkedList<IdFrec>();
        for (NoticiaClasificada nc : llnoticia) {
            vectorC2 = sumaVectores(vectorC2, nc.frecuencia(N));
        }
        for (IdFrec idF : vectorC2) {
            idF.frec = idF.frec / N;
        }
        return vectorC2;
    }

    private LinkedList<IdFrec> sumaVectores(LinkedList<IdFrec> vectorC, Vector<IdFrec> frecuencia) {
        int i = 0;
        int j = 0;
        int N = vectorC.size();
        int M = frecuencia.size();
        LinkedList<IdFrec> aux = new LinkedList<IdFrec>();
        while (i < N && j < M) {
            if (i == j) {
                IdFrec idF = vectorC.get(i);
                idF.frec = idF.frec + frecuencia.get(j).frec;
                aux.addLast(idF);
                i++;
                j++;
            } else if (i < j) {
                aux.addLast(vectorC.get(i));
                i++;
            } else if (i > j) {
                aux.addLast(frecuencia.get(j));
                j++;
            }
        }
        if (i < N) {
            while (i < N) {
                aux.addLast(vectorC.get(i));
                i++;
            }
        }
        if (j < M) {
            while (j < M) {
                aux.addLast(frecuencia.get(j));
                j++;
            }
        }
        return aux;
    }
}
